/**
 * BrandBigData.com Inc.
 * Copyright (c) 2016 All Rights Reserved.
 */
package com.qibao.toolkit.protocol.service;

import com.qibao.toolkit.protocol.exception.ProtocolException;
import com.qibao.toolkit.protocol.facade.*;
import com.qibao.toolkit.protocol.facade.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author xumin
 * @version $Id:ProtocolServiceImpl.java, v0.1 2017/7/4 15:05 xumin
 */
@Service
public class ProtocolServiceImpl implements ProtocolService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolServiceImpl.class);

    @Autowired
    private Map<String, Protocol> protocolMap;

    @Override
    public Response sendRequest(String type, Request request, ProtocolConfiguration config) {
        Protocol protocol = protocolMap.get(type + "Protocol");
        if (null == protocol) {
            throw new ProtocolException("can not find protocol by type:" + type);
        }
        Assert.notNull(request, "request不能为空");
        Assert.hasText(request.getUrl(), "request.url不能为空");
        Assert.notNull(config, "protocol configuration不能为空");
        RetryTemplate retryTemplate = new RetryTemplate();
        retryTemplate.setRetryPolicy(new SimpleRetryPolicy(config.getRetry()));
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(TimeUnit.MINUTES.toMillis(5));
        backOffPolicy.setMultiplier(2);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        try {
            return retryTemplate.execute((context) -> protocol.sendRequest(request, config));
        } catch (Exception e) {
            LOGGER.error("经过重试请求依旧失败：" + e.getMessage(), e);
            Response response = new Response();
            response.setSuccess(false);
            response.setErrorMsg(e.getMessage());
            return response;
        }
    }
}
